//--------------------------------------------------------------------------------------
// File: Tutorial05.fx
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------

//--------------------------------------------------------------------------------------
// Constant Buffer Variables
//--------------------------------------------------------------------------------------

Texture2D txDiffuse : register( t0 );
SamplerState samLinear : register( s0 );


cbuffer ConstantBuffer : register( b0 )
{
	matrix World;
	matrix View;
	matrix Projection;
}

//--------------------------------------------------------------------------------------
struct VS_INPUT
{
    float4 Pos : POSITION;
    float2 Tex : TEXCOORD0;
};

struct GS_INPUT
{
	float4 Pos : SV_POSITION;
	float2 Tex : TEXCOORD0;
	float4 Nomarl:NORMARL0;
	float4 WorldPos : WORLDPOSITION0;
};

struct PS_INPUT
{
    float4 Pos : SV_POSITION;
    float2 Tex : TEXCOORD0;
	float4 Nomarl:NORMARL0;
	float4 WorldPos : WORLDPOSITION0;
};


//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
GS_INPUT VS_Main( VS_INPUT input )
{
	PS_INPUT output = (PS_INPUT)0;
	output.Pos = input.Pos;
	output.WorldPos = mul(input.Pos, World);
	output.Pos = mul(input.Pos,World);
	output.Pos = mul(output.Pos, View);
	output.Pos = mul(output.Pos, Projection);
    output.Tex = input.Tex;
	float4 VNomarl;
	VNomarl.xyz = input.Pos.xyz;
	VNomarl.w = 0;
	VNomarl = mul(VNomarl, World);
	VNomarl = normalize(VNomarl);
	output.Nomarl = VNomarl;

    return output;
}

[maxvertexcount(3)]
void GS_Main(triangle GS_INPUT input[3], inout TriangleStream<PS_INPUT> TriStream)
{
	for (int i = 0; i < 3; i++)
	{
		PS_INPUT Out = (PS_INPUT)0;
		if (input[i].Pos.y < 0|| input[i].Pos.x<0)
		{
			return;
		}
		Out.Pos = input[i].Pos;
		Out.Pos.xyz = Out.Pos.xyz - 0.5 * (input[i].Pos.xyz);
		Out.Pos = mul(Out.Pos,World);
		Out.Pos = mul(Out.Pos, View);
		Out.Pos = mul(Out.Pos, Projection);
		Out.Tex = input[i].Tex;
		Out.Nomarl = input[i].Nomarl;
		Out.WorldPos = input[i].WorldPos;
		TriStream.Append(Out);
	}
	//TriStream.RestartStrip();
	
}


//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS_Main( PS_INPUT input) : SV_Target
{
    float4 Color;
    Color = txDiffuse.Sample( samLinear, input.Tex );

	float3 LigntDir = float3(0, 0, 0) - input.WorldPos.xyz;
	LigntDir = normalize(LigntDir);
	float3 PNormarl = input.Nomarl.xyz;
	PNormarl = normalize(PNormarl);
	float Den = dot(PNormarl, LigntDir);
	if (Den<0)
	{
		Den = 0;
	}
	Den = 0.3 + Den*0.7;
    Color.xyz = Color.xyz*Den;
    return Color;
}
